import logging
import time
from datetime import datetime

import user_agents

from fastapi import Request
from sqlmodel import Session, select

from app.exception.base import AppException, HttpResp
from app.models.system_admin import SystemLoginIn, SystemLoginOut, SystemAdmin
from app.models.system_log_login import SystemLogLogin
from app.core.security import verify_password, create_access_token


class SystemLoginService:
    def __init__(self, request: Request, session: Session):
        self.request: Request = request
        self.session = session

    async def login(self, login_in: SystemLoginIn) -> SystemLoginOut:
        """登录"""
        print('login_in', login_in)
        statement = (
            select(SystemAdmin).where(SystemAdmin.username == login_in.username)
        )
        sys_admin = self.session.exec(statement).one_or_none()
        print('sys_admin', sys_admin)
        if not sys_admin or sys_admin.delete_time:
            await self.record_login_log(0, login_in.username, HttpResp.LOGIN_ACCOUNT_ERROR.msg)
            raise AppException(HttpResp.LOGIN_ACCOUNT_ERROR)
        if sys_admin.is_disable:
            await self.record_login_log(sys_admin.id, sys_admin.username, HttpResp.LOGIN_DISABLE_ERROR.msg)
            raise AppException(HttpResp.LOGIN_DISABLE_ERROR)
        # 对密码加盐
        if not verify_password(login_in.password, sys_admin.password):
            await self.record_login_log(sys_admin.id, sys_admin.username, HttpResp.LOGIN_ACCOUNT_ERROR.msg)
            raise AppException(HttpResp.LOGIN_ACCOUNT_ERROR)
        try:
            jwt_data = {
                "user_id": sys_admin.id,
                "username": sys_admin.username,
                "is_super": sys_admin.is_super,
            }

            jwt_token = create_access_token(subject=jwt_data)

            # 更新登录信息
            sys_admin.last_login_ip = self.request.client.host
            sys_admin.last_login_time = datetime.now()
            self.session.add(sys_admin)
            self.session.commit()
            # 记录登录日志
            await self.record_login_log(sys_admin.id, sys_admin.username)
            # 返回登录信息
            return SystemLoginOut(token=jwt_token)
        except Exception as e:
            err_msg = str(e)
            await self.record_login_log(sys_admin.id, sys_admin.username, err_msg if err_msg else '未知错误')
            raise AppException(HttpResp.FAILED, echo_exc=True)

    async def logout(self):
        """退出"""
        # await RedisUtil.delete(f'{AdminConfig.backstage_token_key}{logout_in.token}')
        return True

    async def record_login_log(self, admin_id: int, username: str, error: str = ''):
        """记录登录日志"""
        ua = user_agents.parse(self.request.headers.get('user-agent', ''))
        try:
            row = SystemLogLogin(
                admin_id=admin_id,
                username=username,
                ip=self.request.client.host,
                os=ua.os.family,
                browser=ua.browser.family,
                status=0 if error else 1,
                create_time=int(time.time())
            )
            self.session.add(row)
            self.session.commit()
        except Exception as e:
            logging.error('记录登录日志异常 %s', str(e))
